﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Caching;
using Memcached.ClientLibrary;

namespace olierFrm.GeneralCache
{
    internal class MemcachedCache : ObjectCache, ICacheBuilder
{
    
    private MemcachedClient _client = null;

    
    public MemcachedCache()
    {
        this._client = MemcachedClientService.Instance.Client;
    }

    public override CacheItem AddOrGetExisting(CacheItem value, CacheItemPolicy policy)
    {
        CacheItem item = this.GetCacheItem(value.Key, value.RegionName);
        if (item == null)
        {
            this.Set(value, policy);
            return value;
        }
        return item;
    }

    public override object AddOrGetExisting(string key, object value, DateTimeOffset absoluteExpiration, string regionName = null)
    {
        CacheItem item = new CacheItem(key, value, regionName);
        CacheItemPolicy policy = new CacheItemPolicy {
            AbsoluteExpiration = absoluteExpiration
        };
        return this.AddOrGetExisting(item, policy);
    }

    public override object AddOrGetExisting(string key, object value, CacheItemPolicy policy, string regionName = null)
    {
        CacheItem item = this.GetCacheItem(key, regionName);
        if (item == null)
        {
            this.Set(new CacheItem(key, value, regionName), policy);
            return value;
        }
        return item.Value;
    }

    public override bool Contains(string key, string regionName = null)
    {
        return this._client.KeyExists(key);
    }

    public override CacheEntryChangeMonitor CreateCacheEntryChangeMonitor(IEnumerable<string> keys, string regionName = null)
    {
        throw new NotImplementedException();
    }

    public override object Get(string key, string regionName = null)
    {
        key = key.ToLower();
        return this._client.Get(key);
    }

    public override CacheItem GetCacheItem(string key, string regionName = null)
    {
        object value = this.Get(key, regionName);
        if (value != null)
        {
            return new CacheItem(key, value, regionName);
        }
        return null;
    }

    public override long GetCount(string regionName = null)
    {
        return -1L;
    }

    protected override IEnumerator<KeyValuePair<string, object>> GetEnumerator()
    {
        throw new NotImplementedException();
    }

    public ObjectCache GetInstance()
    {
        return this;
    }

    public override IDictionary<string, object> GetValues(IEnumerable<string> keys, string regionName = null)
    {
        throw new NotImplementedException();
    }

    public override object Remove(string key, string regionName = null)
    {
        key = key.ToLower();
        return this._client.Delete(key);
    }

    public override void Set(CacheItem item, CacheItemPolicy policy)
    {
        if ((item != null) && (item.Value != null))
        {
            item.Key = item.Key.ToLower();
            if (((policy != null) && (policy.ChangeMonitors != null)) && (policy.ChangeMonitors.Count > 0))
            {
                throw new NotSupportedException("Change monitors are not supported");
            }
            if (policy == null)
            {
                this._client.Add(item.Key.ToString(), item.Value);
            }
            this._client.Add(item.Key.ToString(), item.Value, policy.AbsoluteExpiration.DateTime);
        }
    }

    public override void Set(string key, object value, DateTimeOffset absoluteExpiration, string regionName = null)
    {
        CacheItem item = new CacheItem(key, value, regionName);
        CacheItemPolicy policy = new CacheItemPolicy {
            AbsoluteExpiration = absoluteExpiration
        };
        this.Set(item, policy);
    }

    public override void Set(string key, object value, CacheItemPolicy policy, string regionName = null)
    {
        this.Set(new CacheItem(key, value, regionName), policy);
    }

    
    public override DefaultCacheCapabilities DefaultCacheCapabilities
    {
        get
        {
            return (DefaultCacheCapabilities.CacheRegions | DefaultCacheCapabilities.SlidingExpirations | DefaultCacheCapabilities.AbsoluteExpirations | DefaultCacheCapabilities.OutOfProcessProvider);
        }
    }

    public string DefaultRegionName
    {
        get
        {
            throw new NotImplementedException();
        }
    }

    public override object this[string key]
    {
        get
        {
            return this.Get(key, null);
        }
        set
        {
            this.Set(key, value, (CacheItemPolicy) null, null);
        }
    }

    public override string Name
    {
        get
        {
            return "MemcachedProvider";
        }
    }
}

 

}
